<template>
  <div class="mrp-calculator">
    <h1>黍米酿造 MRP 计算工具</h1>

    <div class="input-group">
      <label>总需求量 (吨):</label>
      <input type="number" v-model="inputs.totalDemand" step="0.01">
    </div>
    <div class="input-group">
      <label>日需求量 (吨):</label>
      <input type="number" v-model="inputs.dailyDemand" step="0.01">
    </div>
    <div class="input-group">
      <label>最优订货批量 (吨):</label>
      <input type="number" v-model="inputs.orderQty" step="1">
    </div>
    <div class="input-group">
      <label>订货点 (吨):</label>
      <input type="number" v-model="inputs.reorderPoint" step="1">
    </div>
    <div class="input-group">
      <label>订货提前期 (天):</label>
      <input type="number" v-model="inputs.leadTime" step="1">
    </div>
    <div class="input-group">
      <label>生产开始时间:</label>
      <input type="date" v-model="inputs.startDate">
    </div>
    <div class="input-group">
      <label>初始库存 (吨):</label>
      <input type="number" v-model="inputs.initialStock" step="0.01">
    </div>

    <button @click="calculateMRP">计算 MRP 计划</button>

    <h2>订单与到货信息</h2>
    <table id="orderTable">
      <thead>
        <tr><th>序号</th><th>发出订单日期</th><th>到货日期</th><th>到货后库存 (吨)</th></tr>
      </thead>
      <tbody>
        <tr v-for="(order, index) in orders" :key="index">
          <td>{{ index + 1 }}</td>
          <td>{{ formatDate(order.orderDate) }}</td>
          <td>{{ formatDate(order.arrivalDate) }}</td>
          <td>{{ order.arrivalStock.toFixed(2) }}</td>
        </tr>
      </tbody>
    </table>

    <h2>每日库存计划（按日开始库存）</h2>
    <table id="stockTable">
      <thead>
        <tr><th>计划日期</th><th>黍米 (吨)</th><th>事件</th></tr>
      </thead>
      <tbody>
        <tr v-for="(stock, index) in stockPlan" :key="index">
          <td>{{ formatMonthDay(stock.date) }}</td>
          <td>{{ stock.amount.toFixed(2) }}</td>
          <td>{{ stock.event }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'

interface Order {
  orderDate: Date
  arrivalDate: Date
  arrivalStock: number
}

interface StockPlan {
  date: Date
  amount: number
  event: string
}

const inputs = reactive({
  totalDemand: 2464.65,
  dailyDemand: 41.08,
  orderQty: 1081,
  reorderPoint: 535,
  leadTime: 10,
  startDate: '2025-09-01',
  initialStock: 780
})

const orders = ref<Order[]>([])
const stockPlan = ref<StockPlan[]>([])

const addDays = (date: Date, days: number): Date => {
  const result = new Date(date)
  result.setDate(result.getDate() + days)
  return result
}

const formatDate = (date: Date): string => {
  return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`
}

const formatMonthDay = (date: Date): string => {
  return `${date.getMonth() + 1}.${date.getDate()}`
}

const calculateMRP = () => {
  // 获取输入
  const totalDemand = parseFloat(inputs.totalDemand as unknown as string)
  const dailyDemand = parseFloat(inputs.dailyDemand as unknown as string)
  const orderQty = parseFloat(inputs.orderQty as unknown as string)
  const reorderPoint = parseFloat(inputs.reorderPoint as unknown as string)
  const leadTime = parseInt(inputs.leadTime as unknown as string)
  const startDate = new Date(inputs.startDate)
  const initialStock = parseFloat(inputs.initialStock as unknown as string)

  if ([totalDemand, dailyDemand, orderQty, reorderPoint, leadTime, initialStock].some(isNaN)) {
    alert('请填写所有有效数值')
    return
  }

  const totalDays = Math.ceil(totalDemand / dailyDemand)

  // === 核心模拟：带"是否已有在途订单"标志 ===
  let currentStock = initialStock
  let currentDate = new Date(startDate)
  const orderList: Order[] = [] // 记录所有订单
  const arrivals = new Map<string, number>() // dateStr => total qty arriving that day
  const orderEvents = new Set<string>() // 用于标注订货日（date string）
  let hasPendingOrder = false // 关键：是否有未到货的订单

  // 第一步：模拟每一天，决定是否下单
  for (let day = 0; day < totalDays; day++) {
    const dateStr = currentDate.toDateString()

    // 1. 先处理早晨到货（如果有）
    if (arrivals.has(dateStr)) {
      currentStock += arrivals.get(dateStr)!
      // 到货后，pending 订单完成
      hasPendingOrder = false
    }

    // 2. 检查是否需要下单：库存 <= ROP 且无在途订单
    if (currentStock <= reorderPoint && !hasPendingOrder) {
      const orderDate = new Date(currentDate)
      const arrivalDate = addDays(orderDate, leadTime)
      orderList.push({ orderDate, arrivalDate, arrivalStock: 0 })
      orderEvents.add(dateStr)

      // 注册到货
      const arrivalDateStr = arrivalDate.toDateString()
      arrivals.set(arrivalDateStr, (arrivals.get(arrivalDateStr) || 0) + orderQty)
      hasPendingOrder = true // 标记有在途订单
    }

    // 3. 当天结束：消耗需求
    currentStock -= dailyDemand
    if (currentStock < 0) currentStock = 0

    // 推进日期
    currentDate = addDays(currentDate, 1)
  }

  // === 重新模拟，计算每次到货后的精确库存（用于表格）===
  const arrivalStockMap = new Map<string, number>()
  let simStock = initialStock
  let simDate = new Date(startDate)
  const simArrivals = new Map<string, number>(
    orderList.map(o => [o.arrivalDate.toDateString(), orderQty])
  )

  for (let day = 0; day < totalDays; day++) {
    const dStr = simDate.toDateString()
    if (simArrivals.has(dStr)) {
      simStock += simArrivals.get(dStr)!
      arrivalStockMap.set(dStr, simStock) // 到货后、消耗前的库存
    }
    simStock -= dailyDemand
    if (simStock < 0) simStock = 0
    simDate = addDays(simDate, 1)
  }

  // 更新订单到货后的库存
  orderList.forEach(order => {
    const arrivalDateStr = order.arrivalDate.toDateString()
    const arrivalStock = arrivalStockMap.get(arrivalDateStr) ?? orderQty
    order.arrivalStock = arrivalStock
  })

  orders.value = orderList

  // === 生成每日库存表（最多30天）===
  const displayDays = Math.min(totalDays, 30)
  const stockPlanList: StockPlan[] = []

  let displayStock = initialStock
  let displayDate = new Date(startDate)
  const displayArrivals = new Map<string, number>(
    orderList.map(o => [o.arrivalDate.toDateString(), orderQty])
  )
  const displayOrderEvents = new Set<string>(
    orderList.map(o => o.orderDate.toDateString())
  )

  for (let i = 0; i < displayDays; i++) {
    const dStr = displayDate.toDateString()
    let event = ''

    // 记录当日开始库存
    const startOfDayStock = displayStock;

    // 早晨到货
    if (displayArrivals.has(dStr)) {
      displayStock += displayArrivals.get(dStr)!
      event += `【到货 ${displayArrivals.get(dStr)} 吨，到货后库存 ${displayStock.toFixed(2)} 吨】`
    }

    // 是否是订货日
    if (displayOrderEvents.has(dStr)) {
      event += '【订货】'
    }

    // 日终消耗
    displayStock -= dailyDemand
    if (displayStock < 0) displayStock = 0

    stockPlanList.push({
      date: new Date(displayDate),
      amount: startOfDayStock,
      event: event
    })

    displayDate = addDays(displayDate, 1)
  }

  stockPlan.value = stockPlanList
}
</script>

<style scoped>
.mrp-calculator {
  padding: 20px;
  max-width: 900px;
  margin: 0 auto;
}

.mrp-calculator h1,
.mrp-calculator h2 {
  color: #2c3e50;
}

.mrp-calculator table {
  border-collapse: collapse;
  margin: 15px 0;
  width: 100%;
}

.mrp-calculator th,
.mrp-calculator td {
  border: 1px solid #ccc;
  padding: 8px 12px;
  text-align: left;
}

.mrp-calculator th {
  background-color: #f9f9f9;
}

.mrp-calculator input,
.mrp-calculator button {
  padding: 6px;
  margin: 4px;
}

.mrp-calculator button {
  background-color: #3498db;
  color: white;
  border: none;
  cursor: pointer;
}

.mrp-calculator button:hover {
  background-color: #2980b9;
}

.input-group {
  margin-bottom: 15px;
}

label {
  display: inline-block;
  width: 180px;
}

.highlight {
  font-weight: bold;
  color: #e74c3c;
}
</style>